package net.kong.sns.rest.client;

import net.kong.sns.rest.client.model.LoginResult;
import net.kong.sns.rest.client.model.UserAuth;
import net.kong.sns.rest.client.model.UserInfo;
import net.kong.sns.rest.client.model.UserRelation;
import net.kong.sns.rest.client.model.FriendInfo;
import net.kong.sns.rest.client.model.PayRegOrderResponse;
import net.kong.sns.rest.client.model.Pay4TestRegOrderResponse;
import java.util.Collection;
import java.util.List;
import java.util.Set;

/**
 * @author <a href="mailto:lanhuai@gmail.com">Ning Yubin</a> , Wang Yuanming
 * @version $Id: Client.java,v 1.11.2.2 2009/12/29 07:47:20 wangyuanming Exp $
 */
public interface Client {

    /**
     * users.getInfo<br/>
     * 获取用户信息，包含所有字段
     * 
     * @param userId 用户ID
     * @return 用户信息
     */
    UserInfo getUserInfo(long userId);

    /**
     * users.getInfo<br/>
     * 获取用户信息，包含指定的字段
     * 
     * @param userId 用户ID
     * @param fields 需要的字段
     * @return 用户信息
     */
    UserInfo getUserInfo(long userId, UserInfo.Field[] fields);

    /**
     * users.getInfo<br/>
     * 获取用户信息，包含指定的字段
     * 
     * @param userIds 用户id数组
     * @param fields 需要的字段
     * @return 用户信息
     */
    Set<UserInfo> getUserInfo(Long[] userIds, UserInfo.Field[] fields);

    /**
     * users.getLoggedInUser 根据当前session_key字符串获取登录用户的userid
     * 
     * @return 用户ID
     */
    Long getLoggedInUser();

    /**
     * users.getLoggedInUser 根据当前session_key从RestServer获取登录用户的userid
     * 
     * @return 用户ID
     */
    Long getLoggedInUserRest();

    /**
     * users.getStandardInfo<br/>
     * 返回特定的用户基本信息列表，包含所有字段。此操作不需要提供session_key, 所返回的基本信息只作为应用程序本身使用（如数据分析之用），而不作为用户展示的数据。如果需要向用户展示个人信息，请使用users.getInfo接口
     * 
     * @param userId 用户ID
     * @return 用户信息
     */
    UserInfo getStandardInfo(long userId);

    /**
     * users.getStandardInfo<br/>
     * 返回特定的用户基本信息列表，包含指定的字段。此操作不需要提供session_key, 所返回的基本信息只作为应用程序本身使用（如数据分析之用），而不作为用户展示的数据。如果需要向用户展示个人信息，请使用users.getInfo接口
     * 
     * @param userIds 用户ID
     * @param fields 需要的字段
     * @return 用户信息
     */
    Set<UserInfo> getStandardInfo(Long[] userIds, UserInfo.Field[] fields);

    /**
     * 判断用户是否授权了应用
     * 
     * @return 授权信息
     */
    UserAuth isAppUser();

    /**
     * 判断用户是否授权了应用
     * 
     * @param userIds 用户ID
     * @return 授权信息
     */
    Set<UserAuth> isAppUser(Long[] userIds);

    /**
     * 判断两组用户是否互为好友关系
     * 
     * @param userIds1 用户组1
     * @param userIds2 用户组2
     * @return 关系列表
     */
    List<UserRelation> friends_areFriends(Collection<Long> userIds1, Collection<Long> userIds2);

    /**
     * 获取指定用户的好友列表
     * 
     * @param userid 用户ID
     * @return 好友ID列表
     */
    List<Long> friends_get_id(Long userid);

    /**
     * 获取指定用户的好友列表(有好友基本信息)
     * 
     * @param userid 用户ID
     * @return 好友信息列表
     */
    List<FriendInfo> friends_get_info(Long userid);

    /**
     * 获取当前用户好友中授权过此应用的好友列表
     * 
     * @return 好友ID列表
     */
    List<Long> friends_getAppUsers_id();

    /**
     * 获取当前用户好友中授权过此应用的好友列表 (有好友基本信息)
     * 
     * @return 好友信息列表
     */
    List<FriendInfo> friends_getAppUsers_info();

    /**
     * 好友动态发布接口
     * 
     * @param templateId 动态Feed模板ID
     * @param data 动态内容
     * @param equalKey 标示同一动作针对不同用户产生的类似动态
     */
    void publishUserAction(long templateId, String data, String equalKey);

    /**
     * 好友动态发布接口
     * 
     * @param templateId 动态Feed模板ID
     * @param data 动态内容
     */
    void publishUserAction(long templateId, String data);

    /**
     * 发送应用类消息
     * 
     * @param receiverId 消息接收者ID
     * @param content 消息内容
     * @param replyId 回复消息的id
     */
    void sendMessage(long receiverId, String content, Long replyId);

    /**
     * 发送应用类消息
     * 
     * @param receiverId 消息接收者ID
     * @param content 消息内容
     */
    void sendMessage(long receiverId, String content);

    /**
     * 预存入用户在应用中消费产生的订单数据，消费数额等信息，返回保证一个用户某次在一个应用中支付安全性的Token。需要注意的必须保证某次调用接口参数唯一的订单号，已取得Token的订单号不要再调用此接口
     * 
     * @param orderId 订单号
     * @param amount 金额
     * @param payType 消费类型，目前只有K金
     * @param desc 描述
     * @param remark1 remark1和remark2可以传第三方认为需要的参数，我这边不做解析，最后在回调payCallbackURL的时候还返回给调用方
     * @param remark2 remark1和remark2可以传第三方认为需要的参数，我这边不做解析，最后在回调payCallbackURL的时候还返回给调用方
     * @return 其中token不为""表示创建成功，否则code<br/>
     *         100003 - 第三方应用的订单已存在<br/>
     *         100004 - token重复<br/>
     *         100005 - session_key不匹配<br/>
     *         100006 - token不匹配<br/>
     *         100007 - 订单不存在<br/>
     *         100008 - 订单状态不正确<br/>
     *         000000 - 系统异常<br/>
     *         100100 - K金帐户不存在<br/>
     *         100101 - K金余额不足<br/>
     *         100102 - K金帐户被冻结<br/>
     */
    PayRegOrderResponse pay_regOrder(long orderId, long amount, PayRegOrderResponse.PayType payType, String desc, String remark1,
            String remark2);

    /**
     * 查询某个用户在一个应用中一次消费是否完成
     * 
     * @param orderId 用户消费订单号
     * @return true - 完成, false - 未完成
     */
    boolean pay_isCompleted(long orderId);

    /**
     * 只用于开发者模拟支付的测试，功能与{@link #pay_regOrder(long, long, net.kong.sns.rest.client.model.PayRegOrderResponse.PayType, String, String, String)}一样
     * 
     * @param orderId 订单号
     * @param amount 金额
     * @param payType 消费类型，目前只有K金
     * @param desc 描述
     * @param remark1 remark1和remark2可以传第三方认为需要的参数，我这边不做解析，最后在回调payCallbackURL的时候还返回给调用方
     * @param remark2 remark1和remark2可以传第三方认为需要的参数，我这边不做解析，最后在回调payCallbackURL的时候还返回给调用方
     * @return 其中token不为""表示创建成功，否则code<br/>
     *         100003 - 第三方应用的订单已存在<br/>
     *         100004 - token重复<br/>
     *         100005 - session_key不匹配<br/>
     *         100006 - token不匹配<br/>
     *         100007 - 订单不存在<br/>
     *         100008 - 订单状态不正确<br/>
     *         000000 - 系统异常<br/>
     *         100100 - K金帐户不存在<br/>
     *         100101 - K金余额不足<br/>
     *         100102 - K金帐户被冻结<br/>
     */
    Pay4TestRegOrderResponse pay4Test_regOrder(long orderId, long amount, Pay4TestRegOrderResponse.PayType payType, String desc,
            String remark1, String remark2);

    /**
     * 只用于开发者模拟支付的测试，功能与{@link #pay_isCompleted(long)}一样
     * 
     * @param orderId 用户消费订单号
     * @return true - 完成, false - 未完成
     */
    boolean pay4Test_isCompleted(long orderId);

    /**
     * 通过用户名和密码登录授权 获取SessionKey 
     * <b>注意</b>:此方法只能由通过认证的信任应用才可以使用
     * @param usernameOrMobile 用户名或者手机号
     * @param password 密码
     * @return {@link LoginResult}  包含SessionKey 和用户基本信息
     */
    LoginResult login(String usernameOrMobile,String password);
    
    /**
     * 设置Client的sessionKey
     * 当客户端程序通过登录的方式获取到sessionKey后，需要为Client设置sessionKey.
     * @param sessionKey
     * @see #login(String, String)
     */
    void setSessionKey(String sessionKey);
}